package com.gitee.yongzhuzl.commonutil.util.dozer;

import org.dozer.Mapper;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * description: DozerBean转换器
 * @author 朱正磊
 * @date 2019-10-30 17:04:07
 */
@Component
public class DozerBeanConverter {

    @Resource
    private Mapper zdyDozerMapper;

    /**
     * description: 实体类转换器（List集合）
     * @author 朱正磊
     * @date 2019-10-28 13:28:03
     * @param sourceList 原实体对象List集合
     * @param targetClass 目标类
     * @param <S> 泛型S
     * @param <T> 泛型T
     * @return 返回目标对象List集合
     */
    public <S, T> List<T> convert(List<S> sourceList, Class<T> targetClass) {
        Assert.notNull(sourceList, "原实体对象List集合不能为空！");
        Assert.notNull(targetClass, "目标类不能为空！");
        List<T> list = new ArrayList<>();
        for (S source : sourceList) {
            list.add(zdyDozerMapper.map(source, targetClass));
        }
        return list;
    }

    /**
     * description: 实体类转换器（Set集合）
     * @author 朱正磊
     * @date 2019-10-28 13:33:54
     * @param sourceSet 原实体对象Set集合
     * @param targetClass 目标类
     * @param <S> 泛型S
     * @param <T> 泛型T
     * @return 返回目标对象Set集合
     */
    public <S, T> Set<T> convert(Set<S> sourceSet, Class<T> targetClass) {
        Assert.notNull(sourceSet, "原实体对象Set集合不能为空！");
        Assert.notNull(targetClass, "目标类不能为空！");
        Set<T> set = new LinkedHashSet<>();
        for (S source : sourceSet) {
            set.add(zdyDozerMapper.map(source, targetClass));
        }
        return set;
    }

    /**
     * description: 实体类转换器（数组）
     * @author 朱正磊
     * @date 2019-10-28 15:51:23
     * @param sourceArray 原实体对象数组
     * @param targetClass 目标类
     * @param <S> 泛型S
     * @param <T> 泛型T
     * @return 返回目标对象数组
     */
    @SuppressWarnings("unchecked")
    public <S, T> T[] convert(S[] sourceArray, Class<T> targetClass) {
        Assert.notNull(sourceArray, "原实体对象数组不能为空！");
        Assert.notNull(targetClass, "目标类不能为空！");
        T[] array = (T[]) Array.newInstance(targetClass, sourceArray.length);
        for (int i = 0; i < sourceArray.length; i++) {
            array[i] = zdyDozerMapper.map(sourceArray[i], targetClass);
        }
        return array;
    }

    /**
     * description: 实体类转换器
     * @author 朱正磊
     * @date 2019-10-28 13:39:40
     * @param source 原实体对象
     * @param targetClass 目标类
     * @param <S> 泛型S
     * @param <T> 泛型T
     * @return 返回目标对象
     */
    public <S, T> T convert(S source, Class<T> targetClass) {
        Assert.notNull(source, "原实体对象不能为空！");
        Assert.notNull(targetClass, "目标类不能为空！");
        return zdyDozerMapper.map(source, targetClass);
    }

    /**
     * description: 实体类转换器
     * @author 朱正磊
     * @date 2019-10-28 13:42:44
     * @param source 原实体对象
     * @param target 目标对象
     * @param <S> 泛型S
     * @param <T> 泛型T
     */
    public <S, T> void convert(S source, T target) {
        Assert.notNull(source, "原实体对象不能为空！");
        Assert.notNull(target, "目标对象不能为空！");
        zdyDozerMapper.map(source, target);
    }

}
